/**
 * 
 */
package com.ibm.moa.outmail.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Base64;

import com.alibaba.fastjson.JSON;
import com.beetstra.jutf7.CharsetProvider;
import com.ibm.moa.outmail.MailApplication;
import com.ibm.moa.outmail.module.MailInfo;
import com.ibm.moa.outmail.module.MailProvider.Providers.Provider;
import com.ibm.moa.outmail.service.ImailService;
import com.ibm.moa.outmail.utils.FileUtil;
import com.ibm.moa.outmail.utils.MD5Encryptor;
import com.ibm.moa.outmail.utils.PropertiesUtils;
import com.ibm.moa.outmail.utils.RFC2047Decoder;
import com.ibm.moa.outmail.utils.StringUtil;
import com.ibm.moa.outmail.utils.Utils;

/**
 * @author user
 * 
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ImailServiceImpl implements ImailService {

	// 连接pop3服务器的主机名、协议、用户名、密码
	public static String MAILSERVER = PropertiesUtils.singlton().getProperty("IMAP_SERVER");
	public static String PROTOCOL = PropertiesUtils.singlton().getProperty("PROTOCOL");
	public static int IMAP_PORT = Integer.parseInt(PropertiesUtils.singlton().getProperty("IMAP_PORT"));
	public static String SMTP_SERVER = PropertiesUtils.singlton().getProperty("SMTP_SERVER");
	public static int SMTP_PORT = Integer.parseInt(PropertiesUtils.singlton().getProperty("SMTP_PORT"));
	public static String MAILPATH = PropertiesUtils.singlton().getProperty("MAILPATH");
	public static String userType = PropertiesUtils.singlton().getProperty("LOGINTYPE");

	public ImailServiceImpl() {
		if (MailApplication.provider != null) {
			final Provider mProvider = MailApplication.provider;
			MAILSERVER = mProvider.getIncoming();
			SMTP_SERVER = mProvider.getOutgoing();
			PROTOCOL = mProvider.getProtocol();
			IMAP_PORT = Utils.parseInt(mProvider.getIncomingport());
			SMTP_PORT = Utils.parseInt(mProvider.getOutgoingport());
			MAILPATH = mProvider.getDomain();
			userType = mProvider.getUsername();
		}
	}

	// static {
	// if (MailApplication.provider != null) {
	// final Provider mProvider = MailApplication.provider;
	// MAILSERVER = mProvider.getIncoming();
	// PROTOCOL = mProvider.getProtocol();
	// IMAP_PORT = Utils.parseInt(mProvider.getIncomingport());
	// SMTP_PORT = Utils.parseInt(mProvider.getOutgoingport());
	// MAILPATH = mProvider.getDomain();
	// userType = mProvider.getUsername();
	// }
	// }

	/**
	 * <p>
	 * 获得连接对象
	 * </p>
	 * Created on 2012-9-12
	 * 
	 * @author: [张役兵]
	 * @update: [日期YYYY-MM-DD] [更改人姓名]
	 */
	private List<Object> getMailFolder(String userCode, String password, int type) throws Exception {
		Store store = null;
		Folder inbox = null;
		try {
			Properties props = System.getProperties();
			Session session = Session.getDefaultInstance(props);
			if ("email".equals(userType)) {
				userCode = userCode + "@" + MAILPATH;
			}
			// 第1个参数为接受协议，第2个参数为邮件接收服务器的地址，第三个参数为pop3协议的端口，最后两个为用户名和密码
			URLName urln = new URLName(PROTOCOL, MAILSERVER, IMAP_PORT, null, userCode, password);
			// 使用URLName指定Session邮件环境，包括认证信息
			store = session.getStore(urln);
			// 连接邮件服务器
			store.connect();
			session.setDebug(false);
			// 从邮件服务器中返回邮箱内的信息
			inbox = store.getFolder("INBOX");
			if (inbox == null)
				throw new Exception("No Inbox");
			inbox.open(type);
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (MessagingException e) {
			e.printStackTrace();
			if (e instanceof javax.mail.AuthenticationFailedException) {
				throw new RuntimeException("用户名或密码错误");
			} else {
				throw new RuntimeException(e);
			}
		}
		List<Object> list = new ArrayList<Object>();
		list.add(store);
		list.add(inbox);
		return list;
	}

	/**
	 * <p>
	 * 获取收件箱列表
	 * </p>
	 * Created on 2012-9-12
	 * 
	 * @author:　[张役兵]
	 * @update:[日期YYYY-MM-DD] [更改人姓名]
	 */
	public String getImailList(String userCode, String password, int pageNo, int pageSize, String note) {
		HashMap hRet = new HashMap();
		List mailList = new ArrayList();
		Store store = null;
		Folder inbox = null;
		try {
			// 获得邮件操作对象
			List<Object> fList = getMailFolder(userCode, password, Folder.READ_ONLY);
			store = (Store) fList.get(0);
			inbox = (Folder) fList.get(1);
			FetchProfile profile = new FetchProfile();
			profile.add(FetchProfile.Item.ENVELOPE);
			profile.add(FetchProfile.Item.FLAGS);
			profile.add(FetchProfile.Item.CONTENT_INFO);
			int mailCount = inbox.getMessageCount();
			// 添加邮件数量，未读数量，最新邮件数量
			hRet.put("mail_cnt", Integer.valueOf(mailCount));
			// hRet.put("mail_urcnt",new
			// Integer(inbox.getUnreadMessageCount()));
			// hRet.put("mail_nmcnt",new Integer(inbox.getNewMessageCount()));
			int startPos, endPos;
			if (pageNo <= 1) {// set pageid=1
				endPos = mailCount;
				startPos = mailCount - pageSize + 1;
				if (startPos < 1)
					startPos = 1;
			} else {
				endPos = mailCount - pageSize * (pageNo - 1);
				startPos = mailCount - pageSize * pageNo + 1;
				if (startPos < 1)
					startPos = 1;
			}
			Message[] msgs = inbox.getMessages(startPos, endPos);
			inbox.fetch(msgs, profile);
			for (int i = msgs.length - 1; i >= 0; i--) {
				Message message = msgs[i];
				MailInfo mailInfo = new MailInfo();
				mailInfo.setMailId(message.getMessageNumber() + "");
				// 是否拥有附件
				try {
					if (message.isMimeType("multipart/mixed")) {
						mailInfo.setHaveAttach(true);
					} else {
						mailInfo.setHaveAttach(false);
					}
				} catch (Exception e) {
					// continue;
				}
				// from
				String from = "";
				String person = "";
				try {
					try {
						InternetAddress address[] = (InternetAddress[]) message.getFrom();
						if (address[0] != null) {
							from = address[0].toString();
							person = address[0].getPersonal();
						}
						from = emailStringToChinese(from);
					} catch (Exception e) {
					}

					// 过滤中文，只留收件人邮箱，格式如：<moa@bmcc.com.cn>
					if (from != null) {

						int kuohaoIndex = from.lastIndexOf("<");
						if (kuohaoIndex != -1) {
							from = from.substring(kuohaoIndex + 1, from.length() - 1);
						}
					}
					mailInfo.setFrom(from);
					if (person == null || person.length() == 0) {
						mailInfo.setMailUserId(from);
					} else {
						mailInfo.setMailUserId(person);
					}
				} catch (Exception exRemoved) {
					exRemoved.printStackTrace();
					continue;
				}
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
				if (message.getSentDate() != null)
					mailInfo.setSendDate(sdf.format(message.getSentDate()));
				else
					mailInfo.setSendDate(sdf.format(new Date()));

				// read flag
				boolean readFlag = false; // no read flag in pop3 server
				if (PROTOCOL.equals("imap")) {
					Flags flags = message.getFlags();
					if (flags.contains(Flags.Flag.SEEN)) {
						readFlag = true;
					}
				}
				mailInfo.setReadFlag(readFlag);
				// subject
				try {
					mailInfo.setSubject(message.getSubject());
					mailInfo.setMailSize(message.getSize());
				} catch (Exception e) {
				}

				mailList.add(mailInfo);
			}
			hRet.put("req_code", "1");
			hRet.put("mail_list", mailList);
		} catch (Exception e) {
			e.printStackTrace();
			hRet = new HashMap();
			hRet.put("req_code", "0");
			String msg = e.getMessage();
			if (msg != null && msg.contains("密码")) {
				hRet.put("req_mess", e.getMessage());
			} else {
				hRet.put("req_mess", "打开邮箱失败");
			}

		} finally {
			try {
				if (inbox != null) {
					inbox.close(false);
				}
				if (store != null) {
					store.close();
				}
			} catch (Exception ex1) {
				ex1.printStackTrace();
				hRet = new HashMap();
				hRet.put("req_code", "0");
				hRet.put("req_mess", "关闭邮件代理失败！");
			}
		}
		String json = null;
		try {
			json = JSON.toJSONString(hRet);
		} catch (Exception e) {
			hRet = new HashMap();
			hRet.put("req_code", "0");
			hRet.put("req_mess", "对象转换异常");
			json = JSON.toJSONString(hRet);
			;
		} catch (Error e) {
			hRet = new HashMap();
			hRet.put("req_code", "0");
			hRet.put("req_mess", "对象转换错误");
			json = JSON.toJSONString(hRet);
		}
		return json;
	}

	/**
	 * 查看邮件详细
	 */
	public String getImailDetail(String userCode, String password, String imailId, String note) {
		Map resMap = new HashMap(4);
		MailInfo mailInfo = new MailInfo();
		Store store = null;
		Folder inbox = null;
		try {
			List<Object> fList = getMailFolder(userCode, password, Folder.READ_WRITE);
			store = (Store) fList.get(0);
			inbox = (Folder) fList.get(1);
			Message msg = null;
			msg = inbox.getMessage(Integer.parseInt(imailId));
			if (msg == null) {
				resMap.put("req_code", "0");
				resMap.put("req_mess", "没有该邮件！");
			} else {
				// 把邮件标记为已读
				msg.setFlag(Flag.SEEN, true);
				mailInfo.setMailId(imailId);
				String from = "";
				String person = "";
				try {
					if (msg.getFrom()[0] != null) {
						from = msg.getFrom()[0].toString();
						person = ((InternetAddress) msg.getFrom()[0]).getPersonal();
					}
					// 注释掉了转换成中文的方法，加上了过滤中文的方法 2011-08-12 xuxiangxun
					from = emailStringToChinese(from);
				} catch (Exception e) {
				}

				// 过滤中文，只留收件人邮箱，格式如：<moa@bmcc.com.cn>
				if (from != null && person != null) {
					int kuohaoIndex = from.indexOf(person);
					if (kuohaoIndex != -1) {
						from = from.substring(kuohaoIndex + person.length());
					}
				}

				mailInfo.setFrom(from);
				if (person == null || person.length() == 0) {
					mailInfo.setMailUserId(from);
				} else {
					person = emailStringToChinese(person);
					mailInfo.setMailUserId(person);
				}

				// date
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
				mailInfo.setSendDate(sdf.format(msg.getSentDate()));

				// subject
				mailInfo.setSubject(msg.getSubject());
				mailInfo.setMailSize(msg.getSize());
				// 是否拥有附件
				try {
					if (msg.isMimeType("multipart/mixed")) {
						mailInfo.setHaveAttach(true);
					} else {
						mailInfo.setHaveAttach(false);
					}
				} catch (Exception e) {
				}

				String mainSendAddr = "";
				String copySendAddr = "";
				String secretSendAddr = "";
				InternetAddress tempAddr[] = null;
				tempAddr = (InternetAddress[]) msg.getRecipients(javax.mail.Message.RecipientType.TO);
				if (tempAddr != null) {
					for (int i = 0; i < tempAddr.length; i++) {
						mainSendAddr = mainSendAddr + tempAddr[i].getAddress() + ";";
					}
				}
				tempAddr = (InternetAddress[]) msg.getRecipients(javax.mail.Message.RecipientType.CC);
				if (tempAddr != null) {
					for (int i = 0; i < tempAddr.length; i++) {
						copySendAddr = copySendAddr + tempAddr[i].getAddress() + ";";
					}
				}
				tempAddr = (InternetAddress[]) msg.getRecipients(javax.mail.Message.RecipientType.BCC);
				if (tempAddr != null) {
					for (int i = 0; i < tempAddr.length; i++) {
						secretSendAddr = secretSendAddr + tempAddr[i].getAddress() + ";";
					}
				}
				mailInfo.setMailCc(copySendAddr);
				mailInfo.setMailBcc(secretSendAddr);
				mailInfo.setRecAddr(mainSendAddr);

				// attachment names
				List attachList = new ArrayList();
				Object content = null;
				try {
					content = msg.getContent();
				} catch (Exception e) {
					e.printStackTrace();
					try {
						if (msg instanceof MimeMessage && "Unable to load BODYSTRUCTURE".equalsIgnoreCase(e.getMessage())) {
							content = new MimeMessage((MimeMessage) msg).getContent();
						}
					} catch (Exception e2) {
						e2.printStackTrace();
					}
				}

				if (content != null) {
					if (content instanceof Multipart)
						parseMultipartContent((Multipart) content, mailInfo, attachList);
					else
						parseContent(msg, mailInfo, attachList);
				}

				mailInfo.setAttachments(attachList);

				String stext = mailInfo.getPlainContent();
				String shtml = mailInfo.getHTMLContent();
				if (stext == null || stext.length() == 0) {
					// System.out.println("----------------------stext--------------------------");
					if (shtml != null && shtml.length() > 0) {
						// System.out.println("----------------------shtml--------------------------");
						stext = StringUtil.deleteHtmlFlag(shtml);
						stext = new StringUtil().deleteHtmlTag(stext);
					} else {
						stext = "";
					}
					mailInfo.setPlainContent(stext);
				}

				if (shtml != null && !"".equals(shtml)) {
					Pattern p = Pattern.compile("<img[^>]*src=\\\"cid:[^>]+>", Pattern.CASE_INSENSITIVE);
					Matcher m = p.matcher(shtml);
					shtml = m.replaceAll("");
				}

				// while (m.find()) {
				// System.out.println("count=>" + m.group());
				// }
				mailInfo.setHTMLContent(shtml);
				parseMailAttachNames(msg, attachList);
				mailInfo.setAttachments(attachList);

				// content info
				// String detail = "";
				// detail = parseMailContent(msg,detail);
				// if(detail==null) detail = "";
				// mailInfo.setPlainContent(detail);
				resMap.put("req_code", "1");
				resMap.put("mailDetail", mailInfo);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			resMap = new HashMap();
			resMap.put("req_code", "0");
			resMap.put("req_mess", "获取邮件详细失败！");
		} catch (Error ex) {
			ex.printStackTrace();
			resMap = new HashMap();
			resMap.put("req_code", "0");
			resMap.put("req_mess", "获取邮件详细失败！");
		} finally {
			try {
				if (inbox != null) {
					inbox.close(false);
				}
				if (store != null) {
					store.close();
				}
			} catch (MessagingException e) {
				e.printStackTrace();
				resMap = new HashMap();
				resMap.put("req_code", "0");
				resMap.put("req_mess", "关闭邮件代理失败！");
			}
		}
		String json = JSON.toJSONString(resMap);
		// System.out.println("--------json.toString()----------"+json.toString());
		return json;
	}

	/**
	 * <p>
	 * 搜索邮件
	 * </p>
	 * <p>
	 * searchCond：检索条件，从发件人和标题中检索。 flag：已读未读状态，0全部，1未读，2已读 默认为0
	 * </p>
	 * 
	 * Created on 2012-9-13
	 * 
	 * @author: [张役兵]
	 * @update: [日期YYYY-MM-DD] [更改人姓名]
	 */
	public String searchMail(String userCode, String password, String searchCond, int flag, int pageNo, int pageSize, String note) {
		HashMap hRet = new HashMap();
		List mailList = new ArrayList();
		Store store = null;
		Folder inbox = null;
		// 邮件数量过多标记
		if (TextUtils.isEmpty(searchCond) && flag == 0) {
			hRet.put("req_code", "0");
			hRet.put("req_mess", "查询条件为空，无法查询！");
		} else {
			try {
				// 获得邮件操作对象
				List<Object> fList = getMailFolder(userCode, password, Folder.READ_WRITE);
				store = (Store) fList.get(0);
				inbox = (Folder) fList.get(1);
				// SearchTerm st = new OrTerm(new BodyTerm(searchCond), new SubjectTerm(searchCond));
				// SearchTerm st = new SubjectTerm(searchCond);
				if (inbox.getMessageCount() > 400) {
					hRet.put("req_code", "0");
					hRet.put("req_mess", "您的邮件数量过多，无法提供搜索！");
				} else {
					Message[] msgs = inbox.getMessages();
					// Message[] msgs = inbox.search(st);
					FetchProfile profile = new FetchProfile();
					profile.add(FetchProfile.Item.ENVELOPE);
					// 如果flag=1 查询邮件标记
					if (flag == 1) {
						profile.add(FetchProfile.Item.FLAGS);
					}
					inbox.fetch(msgs, profile);
					// 定义搜索
					int searchMax = 30;
					List<Message> searchList = new ArrayList<Message>();
					for (int i = msgs.length - 1; i >= 0; i--) {
						Message msg = msgs[i];
						// 当搜索到的结果超过最大结果数量时
						if (searchList.size() >= searchMax) {
							break;
						}
						if (!TextUtils.isEmpty(searchCond) && flag == 1) {
							// 发件人和标题中搜索未读的邮件
						} else if (!TextUtils.isEmpty(searchCond)) {
							// 发件人和标题中搜索
							String subject = msg.getSubject();
							String from = msg.getFrom()[0].toString();
							String person = ((InternetAddress) msg.getFrom()[0]).getPersonal();
							StringBuffer searchBuffer = new StringBuffer("");
							if (!TextUtils.isEmpty(subject)) {
								searchBuffer.append(subject);
							}
							if (!TextUtils.isEmpty(from)) {
								searchBuffer.append(from);
							}
							if (!TextUtils.isEmpty(person)) {
								searchBuffer.append(person);
							}
							String s = searchBuffer.toString();
							if (!TextUtils.isEmpty(s) && s.indexOf(searchCond) >= 0) {
								searchList.add(msg);
							}
						} else {
							// 只搜索未读邮件
							Flags flags = msg.getFlags();
							if (!flags.contains(Flags.Flag.SEEN)) {
								searchList.add(msg);
							}
						}

					}
					if (searchList.size() > 0) {
						// 添加搜索数量
						hRet.put("mail_cnt", Integer.valueOf(searchList.size()));

						Message[] fMsgs = new Message[searchList.size()];
						for (int i = 0; i < searchList.size(); i++) {
							fMsgs[i] = searchList.get(i);
						}
						FetchProfile fp = new FetchProfile();
						fp.add(FetchProfile.Item.ENVELOPE);
						fp.add(FetchProfile.Item.FLAGS);
						fp.add(FetchProfile.Item.CONTENT_INFO);
						inbox.fetch(fMsgs, fp);
						for (int i = 0; i < searchList.size(); i++) {
							Message message = fMsgs[i];
							MailInfo mailInfo = new MailInfo();
							// id
							mailInfo.setMailId(message.getMessageNumber() + "");
							// 是否拥有
							if (message.isMimeType("multipart/mixed")) {
								mailInfo.setHaveAttach(true);
							} else {
								mailInfo.setHaveAttach(false);
							}

							// from
							String from = "";
							String person = "";
							try {
								if (message.getFrom()[0] != null) {
									from = message.getFrom()[0].toString();
									person = ((InternetAddress) message.getFrom()[0]).getPersonal();
								}
								from = emailStringToChinese(from);
								// 过滤中文，只留收件人邮箱，格式如：<moa@bmcc.com.cn>
								if (from != null) {
									int kuohaoIndex = from.lastIndexOf(person);
									if (kuohaoIndex != -1) {
										from = from.substring(kuohaoIndex + person.length());
									}
								}
								mailInfo.setFrom(from);
								if (person == null || person.length() == 0) {
									mailInfo.setMailUserId(from);
								} else {
									person = emailStringToChinese(person);
									mailInfo.setMailUserId(person);
								}
							} catch (javax.mail.MessageRemovedException exRemoved) {
								exRemoved.printStackTrace();
								continue;
							}
							// date
							SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
							mailInfo.setSendDate(sdf.format(message.getSentDate()));

							// read flag
							boolean readFlag = false; // no read flag in pop3
														// server
							if (PROTOCOL.equals("imap")) {
								Flags flags = message.getFlags();
								if (flags.contains(Flags.Flag.SEEN)) {
									readFlag = true;
								}
							}
							mailInfo.setReadFlag(readFlag);
							// subject
							mailInfo.setSubject(message.getSubject());
							mailInfo.setMailSize(message.getSize());
							mailList.add(mailInfo);
						}
						hRet.put("req_code", "1");
						hRet.put("mail_list", mailList);
					} else {
						hRet.put("req_code", "0");
						if (flag == 1) {
							hRet.put("req_mess", "没有未读邮件！");
						} else {
							hRet.put("req_mess", "没有搜索结果！");
						}

					}
				}
				// logService.saveMoaLog(new
				// MoaModuleLog(userCode,MoaModuleLog.SUCCESS,note,null,"外网邮件",null,"搜索邮件"));
			} catch (Exception e) {
				e.printStackTrace();
				hRet = new HashMap();
				hRet.put("req_code", "0");
				hRet.put("req_mess", "搜索邮件失败！");
				// logService.saveMoaLog(new
				// MoaModuleLog(userCode,MoaModuleLog.FAILED,note,null,"外网邮件",null,"搜索邮件"));
			} finally {
				try {
					if (inbox != null) {
						inbox.close(false);
					}
					if (store != null) {
						store.close();
					}
				} catch (Exception ex1) {
					ex1.printStackTrace();
					hRet = new HashMap();
					hRet.put("req_code", "0");
					hRet.put("req_mess", "搜索邮件失败！");
					// logService.saveMoaLog(new
					// MoaModuleLog(userCode,MoaModuleLog.FAILED,note,null,"外网邮件",null,"搜索邮件"));
				}
			}
		}
		String json = JSON.toJSONString(hRet);
		return json;
	}

	/**
	 * <p>
	 * 发送邮件
	 * </p>
	 * <p>
	 * emailAddr:发件人邮件 mailInfo：邮件信息 forwardMailID：转发邮件地址
	 * </p>
	 * <p>
	 * </p>
	 * Created on 2012-9-13
	 * 
	 * @author: [张役兵]
	 * @update: [日期YYYY-MM-DD] [更改人姓名]
	 */
	public String sendEmail(final String userCode, final String password, MailInfo mailInfo, String forwardMailID, String[] attachNames, String note,
			String[] filePathList) {
		HashMap hRet = new HashMap();
		Properties props = new Properties();
		props.put("mail.smtp.host", SMTP_SERVER);// SMTP_SERVER
		props.put("mail.smtp.port", SMTP_PORT);

		// 需要经过授权
		props.put("mail.smtp.auth", "true");
		String email = userCode + "@" + MAILPATH;
		String temp = null;
		if ("email".equals(userType)) {
			temp = email;
		} else {
			temp = userCode;
		}
		final String loginname = temp;
		Session session = Session.getInstance(props);
		// Session session = Session.getInstance(props, new Authenticator() {
		// protected PasswordAuthentication getPasswordAuthentication() {
		// return new PasswordAuthentication(loginname, password);
		// }
		// });
		session.setDebug(false);

		Store store = null;
		Folder inbox = null;

		// 定义消息对象
		MimeMessage forwardMessage = new MimeMessage(session);
		try {
			InternetAddress from = new InternetAddress(email, userCode, "gb2312");
			forwardMessage.setFrom(from);
			if (!TextUtils.isEmpty(mailInfo.getRecAddr())) {
				forwardMessage.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(mailInfo.getRecAddr()));
			}
			if (!TextUtils.isEmpty(mailInfo.getMailCc())) {
				forwardMessage.setRecipients(javax.mail.Message.RecipientType.CC, InternetAddress.parse(mailInfo.getMailCc()));
			}
			if (!TextUtils.isEmpty(mailInfo.getMailBcc())) {
				forwardMessage.setRecipients(javax.mail.Message.RecipientType.BCC, InternetAddress.parse(mailInfo.getMailBcc()));
			}

			String subject;
			if (!TextUtils.isEmpty(mailInfo.getSubject())) {
				subject = mailInfo.getSubject();
			} else {
				subject = "无主题";
			}

			forwardMessage.setSubject(MimeUtility.encodeText(subject, "GB2312", "B"));
			forwardMessage.setSentDate(new Date());

			MimeMultipart forwordPart = new MimeMultipart();
			forwordPart.setSubType("related");
			// 邮件内容改为HTML格式
			MimeBodyPart contentPart = new MimeBodyPart();
			// contentPart.setDisposition(Part.INLINE);
			contentPart.setContent(TextUtils.isEmpty(mailInfo.getPlainContent()) ? "" : mailInfo.getPlainContent().replaceAll("\n", "<br/>"),
					"text/html ;charset=gbk");
			forwordPart.addBodyPart(contentPart);

			// 设置转发内容
			if (!TextUtils.isEmpty(forwardMailID)) {
				Properties prop = new Properties();
				props.put("mail.imap.partialfetch", "false");
				Session forwordSession = Session.getInstance(prop);
				store = forwordSession.getStore(PROTOCOL);

				store.connect(MAILSERVER, IMAP_PORT, loginname, password);

				inbox = store.getDefaultFolder().getFolder("INBOX");
				inbox.open(Folder.READ_ONLY);
				Message messages = inbox.getMessage(Integer.parseInt(forwardMailID));
				if (messages != null) {
					try {
						Multipart multipart = (Multipart) messages.getContent();
						// 判断是否有附件，并对附件进行处理转发
						if (messages.isMimeType("multipart/mixed")) {
							forwordPart.setSubType("mixed");
							for (int i = 0; i < multipart.getCount(); i++) {
								BodyPart bodypart = multipart.getBodyPart(i);
								// 如果该BodyPart对象包含附件，则应该解析出来
								if (bodypart.getDisposition() != null
										&& ((bodypart.getDisposition().equals(Part.ATTACHMENT)) || (bodypart.getDisposition().equals(Part.INLINE)))) {
									MimeBodyPart messageBodyPart = new MimeBodyPart();
									DataHandler dataHandler = bodypart.getDataHandler();
									messageBodyPart.setFileName(MimeUtility.encodeWord(bodypart.getFileName(), "GB2312", null));
									messageBodyPart.setDataHandler(dataHandler);
									forwordPart.addBodyPart(messageBodyPart);
									// forwordPart.addBodyPart(bodypart);
									System.out.println("获取附件成功!!!");
								} else {
									System.out.println("没有附件！！！");
									continue;
								}
							}
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				} else {
					throw new RuntimeException("转发的邮件在服务器上不存在，无法转发");
				}
			}
			if (filePathList != null && filePathList.length > 0) {
				forwordPart.setSubType("mixed");
				for (String filepath : filePathList) {
					MimeBodyPart attch1 = new MimeBodyPart();
					File file = new File(filepath);
					attch1.setFileName(file.getName());
					DataSource ds = new FileDataSource(file);
					DataHandler dh = new DataHandler(ds);
					attch1.setDataHandler(dh);

					forwordPart.addBodyPart(attch1);
				}

			}
			forwardMessage.setContent(forwordPart);
			// 发送邮件
			forwardMessage.saveChanges();
			Transport transport = session.getTransport("smtp");

			transport.connect(SMTP_SERVER, loginname, password);
			transport.sendMessage(forwardMessage, forwardMessage.getAllRecipients());
			transport.close();
			transport = null;
			// Transport.send(forwardMessage, forwardMessage.getAllRecipients());
			hRet.put("req_code", "1");
			hRet.put("req_mess", "邮件发送成功！");
			// logService.saveMoaLog(new
			// MoaModuleLog(userCode,MoaModuleLog.SUCCESS,note,null,"外网邮件",null,"发送邮件"));
		} catch (Exception ex) {
			ex.printStackTrace();
			hRet = new HashMap();
			hRet.put("req_code", "0");
			if (ex instanceof AuthenticationFailedException) {
				hRet.put("req_mess", "用户名密码错误！");
			} else {
				hRet.put("req_mess", "发送邮件失败！");
			}

			// logService.saveMoaLog(new
			// MoaModuleLog(userCode,MoaModuleLog.FAILED,note,null,"外网邮件",null,"发送邮件"));
		} finally {
			try {
				if (inbox != null) {
					inbox.close(false);
				}
				if (store != null) {
					store.close();
				}
			} catch (Exception ex1) {
				ex1.printStackTrace();
				hRet = new HashMap();
				hRet.put("req_code", "0");
				hRet.put("req_mess", "关闭邮件代理失败！");
				// logService.saveMoaLog(new
				// MoaModuleLog(userCode,MoaModuleLog.FAILED,note,null,"外网邮件",null,"发送邮件"));
			}
		}
		String json = JSON.toJSONString(hRet);
		return json;
	}

	/**
	 * <p>
	 * 批量删除邮件
	 * </p>
	 * Created on 2012-9-14
	 * 
	 * @author:　[张役兵]
	 * @update:[日期YYYY-MM-DD] [更改人姓名]
	 */
	public String deleteMail(String userCode, String password, String mailIds, String note) {
		Map resMap = new HashMap(4);
		Store store = null;
		Folder inbox = null;
		try {
			List<Object> fList = getMailFolder(userCode, password, Folder.READ_WRITE);
			store = (Store) fList.get(0);
			inbox = (Folder) fList.get(1);
			String[] ids = mailIds.split(",");
			int[] intIds = new int[ids.length];
			for (int i = 0; i < ids.length; i++) {
				intIds[i] = Integer.parseInt(ids[i]);
				Message msg = inbox.getMessage(intIds[i]);
				if (msg != null) {
					msg.setFlag(Flags.Flag.DELETED, true);
				}
			}
			resMap.put("req_code", "1");
			resMap.put("req_mess", "邮件删除成功！");
		} catch (Exception ex) {
			ex.printStackTrace();
			resMap = new HashMap();
			resMap.put("req_code", "0");
			resMap.put("req_mess", "删除邮件失败！");
		} finally {
			try {
				if (inbox != null) {
					inbox.close(false);
				}
				if (store != null) {
					store.close();
				}
			} catch (MessagingException e) {
				e.printStackTrace();
				resMap = new HashMap();
				resMap.put("req_code", "0");
				resMap.put("req_mess", "关闭邮件代理失败！");
			}
		}
		String json = JSON.toJSONString(resMap);
		return json;
	}

	/**
	 * <p>
	 * 获得邮件附件
	 * </p>
	 * Created on 2012-9-17
	 * 
	 * @author:　[张役兵]
	 * @update:[日期YYYY-MM-DD] [更改人姓名]
	 */
	public String getMailAttach(String userCode, String password, String mailId, String fileName, String requestPath, String note, String fileBasePath) {
		Map resMap = new HashMap();

		Store store = null;
		Folder inbox = null;
		try {
			List<Object> fList = getMailFolder(userCode, password, Folder.READ_ONLY);
			store = (Store) fList.get(0);
			inbox = (Folder) fList.get(1);
			Message msg = inbox.getMessage(Integer.parseInt(mailId));
			if (msg != null) {
				String msgId = null;
				try {
					msgId = ((MimeMessage) msg).getMessageID();
					if (msgId != null) {
						msgId = MD5Encryptor.encrypt(msgId);
					}
				} catch (Exception e) {
				}
				if (msgId == null) {
					msgId = UUID.randomUUID().toString();
				}
				byte[] ret = getAttachment(msg, fileName);
				if (ret != null) {
					// 获得附件根路径
					File dir = new File(Environment.getExternalStorageDirectory(), "moa/outmail/" + userCode + "/" + msgId);
					if (!dir.exists()) {
						dir.mkdirs();
					}
					String basePath = dir.getAbsolutePath();

					// 创建附件
					String name = FileUtil.getFile(ret, basePath, fileName);
					resMap.put("req_code", "1");
					resMap.put("file_name", fileName);
					resMap.put("file_path", basePath + "/" + name);
					resMap.put("file_size", ret.length);
				} else {
					resMap.put("req_code", "0");
					resMap.put("req_mess", "没有此附件");
					resMap.put("file_path", "没有此附件");
				}

			}
			// logService.saveMoaLog(new
			// MoaModuleLog(userCode,MoaModuleLog.SUCCESS,note,null,"外网邮件",null,"查看邮件附件"));
		} catch (Exception ex) {
			ex.printStackTrace();
			resMap = new HashMap();
			resMap.put("req_code", "0");
			resMap.put("req_mess", "查看邮件附件失败！");
			// logService.saveMoaLog(new
			// MoaModuleLog(userCode,MoaModuleLog.FAILED,note,null,"外网邮件",null,"查看邮件附件"));
		} finally {
			try {
				if (inbox != null) {
					inbox.close(false);
				}
				if (store != null) {
					store.close();
				}
			} catch (Exception ex1) {
				ex1.printStackTrace();
				resMap = new HashMap();
				resMap.put("req_code", "0");
				resMap.put("req_mess", "关闭邮件代理失败！");
				// logService.saveMoaLog(new
				// MoaModuleLog(userCode,MoaModuleLog.FAILED,note,null,"外网邮件",null,"查看邮件附件"));
			}
		}
		String json = JSON.toJSONString(resMap);
		System.out.println(json.toString());
		return json;
	}

	/**
	 * <p>
	 * 获得未读外网邮件数量
	 * </p>
	 * <p>
	 * 平台调用
	 * </p>
	 * 返回结果 请求状态-数量 如：请求状态 1成功，0失败 如：1-20 表示请求成功有20条未读邮件 Created on 2012-9-26
	 * 
	 * @author:　[张役兵]
	 * @update:[日期YYYY-MM-DD] [更改人姓名]
	 */
	public String getUnreadEmailNum(String userCode, String password) {
		Store store = null;
		Folder inbox = null;
		String requestString = "";
		int unReadNum = 0;
		try {
			// 获得邮件操作对象
			List<Object> fList = getMailFolder(userCode, password, Folder.READ_ONLY);
			store = (Store) fList.get(0);
			inbox = (Folder) fList.get(1);
			Message[] msgs = inbox.getMessages();
			FetchProfile profile = new FetchProfile();
			profile.add(FetchProfile.Item.FLAGS);
			inbox.fetch(msgs, profile);
			for (int i = msgs.length - 1; i >= 0; i--) {
				Message msg = msgs[i];
				// 只搜索未读邮件
				Flags flags = msg.getFlags();
				if (!flags.contains(Flags.Flag.SEEN)) {
					unReadNum++;
				}

			}
			requestString = 1 + "-" + unReadNum;
		} catch (Exception e) {
			e.printStackTrace();
			requestString = 0 + "-" + unReadNum;
		} finally {
			try {
				if (inbox != null) {
					inbox.close(false);
				}
				if (store != null) {
					store.close();
				}
			} catch (Exception ex1) {
				ex1.printStackTrace();
				requestString = 0 + "-" + unReadNum;
			}
		}
		return requestString;
	}

	private byte[] getAttachment(Part part, String fileName) {
		byte[] ret = null;
		try {
			String disposition = part.getDisposition();
			if (disposition != null && (disposition.equalsIgnoreCase("attachment") || disposition.equalsIgnoreCase("inline"))) {
				// 是附件
				String temp = "";
				temp = getISOFileName(part);
				temp = emailStringToChinese(temp);
				// temp = MimeUtility.decodeText(temp);
				if (temp.equals(fileName)) {
					InputStream is = part.getInputStream();
					byte[] buf = new byte[10240000];
					ret = new byte[0];
					int read = 0;
					while ((read = is.read(buf)) != -1) {
						byte[] newBytes = new byte[ret.length + read];
						System.arraycopy(ret, 0, newBytes, 0, ret.length);
						System.arraycopy(buf, 0, newBytes, ret.length, read);
						ret = newBytes;
					}
					if (is != null) {
						is.close();
					}
					return ret;
				}
			} else if (part.isMimeType("multipart/*")) {
				Object o = part.getContent();
				if (o instanceof Multipart) {
					Multipart multipart = (Multipart) o;
					int counts = multipart.getCount();
					for (int i = 0; i < counts; i++) {
						ret = getAttachment(multipart.getBodyPart(i), fileName);
						if (ret != null) {
							return ret;
						}
					}
				}
			} else {
				Object o = part.getContent();
				if (o instanceof Part) {
					getAttachment((Part) o, fileName);
				}
			}
			/*
			 * else if (part.isMimeType("message/rfc822")) { return getAttachment((Part) part.getContent(), fileName); }
			 */
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	/**
	 * <p>
	 * 字符串中文转化
	 * </p>
	 * Created on 2012-9-11
	 * 
	 * @author: [张役兵]
	 * @update: [日期YYYY-MM-DD] [更改人姓名]
	 */
	public static String emailStringToChinese(String string) throws Exception {
		String lc = string.toLowerCase();
		if (lc.startsWith("=?gb2312") || lc.startsWith("=?gbk") || lc.startsWith("=?utf-8")) {
			string = MimeUtility.decodeText(string);
		} else if (lc.startsWith("=?unicode-1-1-utf-7") || lc.startsWith("=?utf-7")) {
			try {
				Charset mModifiedUtf7Charset = new CharsetProvider().charsetForName("X-RFC-3501");
				CharsetDecoder u7decoder = mModifiedUtf7Charset.newDecoder().onMalformedInput(CodingErrorAction.REPORT);
				CharBuffer cb = u7decoder.decode(ByteBuffer.wrap(string.getBytes("US-ASCII")));
				string = cb.toString();
			} catch (Exception e) {
				throw new RuntimeException("Unable to decode folder name: " + string, e);
			}

		} else if (lc.startsWith("=?ibm-euccn")) {
			RFC2047Decoder decoder = new RFC2047Decoder(RFC2047Decoder.unfold(string));
			string = decoder.get();
		} else if (lc.startsWith("=?unknown")) {
			// sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
			string = new String(Base64.decode(string, Base64.URL_SAFE));
		} else {
			// modify by wangld
			/*
			 * boolean chinese = false; char c; for(int i=0;i<string.length();i++){ c = string.charAt(i); if(c>256 && ((c>=0x3400 && c<=0x4db5) ||
			 * (c>=0x4e00 && c<=0x9fa5))){ chinese = true; } } if(!chinese) string = new String(string.getBytes("ISO-8859-1"), "gb2312");
			 */
			RFC2047Decoder decoder = new RFC2047Decoder(RFC2047Decoder.unfold(string));
			string = decoder.get();
		}
		string = formatName(string);
		return string;
	}

	/**
	 * <p>
	 * 格式化名字
	 * </p>
	 * Created on 2012-9-11
	 * 
	 * @author: [张役兵]
	 * @update: [日期YYYY-MM-DD] [更改人姓名]
	 */
	public static String formatName(String name) {
		String ret = "";
		char ch;
		if (name != null && name.length() > 0) {
			for (int i = 0; i < name.length(); i++) {
				ch = name.charAt(i);
				if (ch != ' ' && ch != '"' && ch != '\'' && ch != '\\' && ch != '/' && ch != ':' && ch != '?' && ch != '*' && ch != '>' && ch != '<'
						&& ch != '|') {
					ret += ch;
				}
			}
		}
		return ret;
	}

	public static String getSubject(Message mimeMessage) {
		String subject = null;
		try {
			subject = mimeMessage.getSubject();
			if (!TextUtils.isEmpty(subject))
				subject = emailStringToChinese(subject);
			else
				subject = "[无标题]";
		} catch (Exception e) {
			e.printStackTrace();
			subject = "[无标题]";
		}
		return subject;
	}

	public static void parseMailAttachNames(Part part, List attachList) {
		try {
			String disposition = part.getDisposition();
			if (disposition != null && (disposition.equals(Part.ATTACHMENT))) {
				// 附件
				String temp = getISOFileName(part);
				String fileName = emailStringToChinese(temp);
				// fileName = MimeUtility.decodeText(temp);
				attachList.add(fileName);
			} else if (part.isMimeType("multipart/*")) {
				if (part instanceof Multipart) {
					Multipart multipart = (Multipart) part; // part.getContent();
					int counts = multipart.getCount();
					for (int i = 0; i < counts; i++) {
						parseMailAttachNames(multipart.getBodyPart(i), attachList);
					}
				}
			} else if (part.isMimeType("message/rfc822")) {
				parseMailAttachNames((Part) part.getContent(), attachList);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String getISOFileName(Part body) {
		// 设置一个标志，判断文件名从Content-Disposition中获取还是从Content-Type中获取
		boolean flag = true;
		if (body == null) {
			return null;
		}
		String[] cdis;
		try {
			cdis = body.getHeader("Content-Disposition");
		} catch (Exception e) {
			return null;
		}
		if (cdis == null) {
			flag = false;
		}
		if (!flag) {
			try {
				cdis = body.getHeader("Content-Type");
			} catch (Exception e) {
				return null;
			}
		}
		if (cdis == null) {
			return null;
		}
		if (cdis[0] == null) {
			return null;
		}
		// 从Content-Disposition中获取文件名
		if (flag) {
			int pos = cdis[0].indexOf("filename=");
			if (pos < 0) {
				return null;
			}
			// 如果文件名带引号
			if (cdis[0].charAt(cdis[0].length() - 1) == '"') {
				int pos2 = cdis[0].indexOf('"', pos + 14);
				if (pos2 > 0) {
					return cdis[0].substring(pos + 10, pos2);
				} else {
					return cdis[0].substring(pos + 10, cdis[0].length() - 1);
				}
			}
			return cdis[0].substring(pos + 9, cdis[0].length());
		} else {
			int pos = cdis[0].indexOf("name=");
			if (pos < 0) {
				return null;
			}
			// 如果文件名带引号
			if (cdis[0].charAt(cdis[0].length() - 1) == '"') {
				return cdis[0].substring(pos + 6, cdis[0].length() - 1);
			}
			return cdis[0].substring(pos + 5, cdis[0].length());
		}
	}

	public static void parseMultipartContent(Multipart multipart, MailInfo mail, List attachs) {
		try {
			int counts = multipart.getCount();
			for (int i = 0; i < counts; i++) {
				parseContent(multipart.getBodyPart(i), mail, attachs);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void parseContent(Part part, MailInfo mail, List attachs) throws Exception {
		String disposition = part.getDisposition();
		if (disposition == null)// 如果附件包含在正文里
		{
			String contentType = part.getContentType().toLowerCase();
			if (contentType.startsWith("text/plain")) {
				String content = "";
				String charset = "utf-8";
				int p = contentType.indexOf("charset");
				if (p != -1) {
					p = contentType.indexOf("=", p + 7);
					if (p != -1)
						charset = contentType.substring(p + 1).trim();
				}
				charset = normailCharset(charset);
				if ("gb2312".equals(charset)) {
					charset = "gbk";
				}
				// String coss=(String)part.getContent();
				InputStream is = part.getInputStream();
				BufferedReader reader = new BufferedReader(new InputStreamReader(is, charset));
				for (String thisLine = reader.readLine(); thisLine != null; thisLine = reader.readLine())
					content += thisLine + "</p>";
				is.close();
				if (null == mail.getPlainContent()) {
					mail.setPlainContent("");
				}
				mail.setPlainContent(mail.getPlainContent() + content);
				// mail.setPlainContent(mail.getPlainContent()+coss);
			} else if (contentType.startsWith("text/html")) {
				String content = "";
				String charset = "utf-8";
				int p = contentType.indexOf("charset");
				if (p != -1) {
					p = contentType.indexOf("=", p + 7);
					if (p != -1)
						charset = contentType.substring(p + 1).trim();
				}
				if ("gb2312".equals(charset)) {
					charset = "gbk";
				}
				charset = normailCharset(charset);
				InputStream is = part.getInputStream();
				BufferedReader reader = new BufferedReader(new InputStreamReader(is, charset));
				for (String thisLine = reader.readLine(); thisLine != null; thisLine = reader.readLine())
					content += thisLine;
				is.close();

				if (null == mail.getHTMLContent()) {
					mail.setHTMLContent("");
				}
				mail.setHTMLContent(mail.getHTMLContent() + content);
			} else if (contentType.startsWith("multipart")) {
				Multipart mp = (Multipart) part.getContent();
				// int index = 0;// 兼容不正确的格式,返回第一个部分
				// if (mp.getCount() > 1)
				// index = 1;// 第2个部分为html格式的哦~
				// Part tmp = mp.getBodyPart(0);
				// parseContent(tmp,mail,attachs);

				int counts = mp.getCount();
				for (int i = 0; i < counts; i++) {
					parseContent(mp.getBodyPart(i), mail, attachs);
				}
				/*
				 * Object o = part.getContent(); if (o instanceof Part) { parseContent((Part) o, mail, attachs); }
				 */
			} else if (contentType.startsWith("message/rfc822")) {
				Part tmp = (Part) part.getContent();
				parseContent(tmp, mail, attachs);
			} else if (contentType.indexOf("name") != -1) {
				String temp = getISOFileName(part);
				String fileName = emailStringToChinese(temp);
				// String fileName = MimeUtility.decodeText(temp);
				attachs.add(fileName);
			}
		} else if (disposition.equalsIgnoreCase("attachment")) {
			String temp = getISOFileName(part);
			String fileName = emailStringToChinese(temp);
			attachs.add(fileName);
		} else if (disposition.equalsIgnoreCase("inline")) {
			String contentType = part.getContentType().toLowerCase();
			boolean conname = false;
			String content = "";
			if (contentType.indexOf("name") != -1)
				conname = true;
			if (part.isMimeType("text/plain") && !conname) {
				content = mail.getPlainContent();
				if (content == null)
					content = "";
				content += (String) part.getContent();
				mail.setPlainContent(content);
			} else if (part.isMimeType("text/html") && !conname) {
				content = mail.getHTMLContent();
				if (content == null)
					content = "";
				content += (String) part.getContent();
				mail.setHTMLContent(content);
			} else {
				String temp = getISOFileName(part);
				String fileName = emailStringToChinese(temp);
				// String fileName = MimeUtility.decodeText(temp);
				attachs.add(fileName);
			}
		} else {
			Object o = part.getContent();
			if (o instanceof Part) {
				parseContent((Part) o, mail, attachs);
			}
		}
	}

	public static String normailCharset(String charset) {
		String ret = "";
		if (charset == null)
			return "GBK";
		int len = charset.length();
		char c;
		for (int i = 0; i < len; i++) {
			c = charset.charAt(i);
			if (c >= 'A' && c <= 'Z')
				ret += c;
			else if (c >= 'a' && c <= 'z')
				ret += c;
			else if (c >= '0' && c <= '9')
				ret += c;
			else if (c == '-' || c == '_')
				ret += c;
		}
		return ret;
	}

	public class MailAutherticator extends Authenticator {

	}
}
